library(tidyverse) # for graphing and data cleaning
library(ggthemes)
library(lubridate) # for working with dates
library(colorRamps)
library(remotes)
library(plotly)
# For the garden data, you need to first install the remotes library, if you haven't already
# Then, install the gardenR library, if you haven't already. Do this by uncommenting the code below (delete the hashtag) and running it. Then, you should delete this line of code or add the hashtag back so you don't reinstall each time.
# `remotes::install_github("llendway/gardenR")
# Once the library is installed, you don't need to install it again, but each time you need to load the library using the code below. You will know if you haven't installed the library if the code below produces an error.
library(gardenR)
theme_set(theme_minimal()) # set a theme if desired
# load the garden data
data(garden_harvest)
Explain the question you hope to answer and create the graph below in
the Graph Week 1 section. For the first week, you may not have the
skills quite yet to create exactly what you want to create - that’s ok!
Get as close as you can, and the instructors will give you feedback to
help you out. You can summarize the data in any way you’d like. Add R
code chunks and comment code as needed. As the weeks go by, you will
continue to build on this file by putting new code in the next Graph
sections. You will keep all the old code, add your instructor’s feedback
by copying and pasting it from moodle (found in the Grade section of
moodle), and make improvements from my suggestions and from other ideas
you have. Having the old code and graphs and the instructor feedback
will help you (and the instructors) easily see the progress throughout
the course.
FYI, Prof. Lisa just added 2021 data to the gardenR
package. If you want to use that data (either with the 2020 data or by
itself), you will need to reinstall the package. Just a warning that
variable names were maintained but names of vegetables and varieties
changed in a few cases over the two years (oops). After you load the
dataset, you can search for gardenR in the Help tab to find out more
about the new datasets.
Graph Week 1
Question I hope to answer: (write your description here - 1-2
sentences should be plenty)
I’m going to try to see what the greatest yield crop is over time-
which time of summer is the “bean” season vs. “pea season”. My approach
is going to be finding the maximum vegetable harvested each day, and
displaying the weight harvested as well.
garden_harvest_maxbyday <- garden_harvest %>%
group_by(date, vegetable) %>%
summarize(veg_total = sum(weight)) %>%
mutate(weight_kg = veg_total/1000) %>%
slice_max(weight_kg, n= 1)
The data should now be grouped by the maximum vegetable harvested
each day, and the weight harvested.
garden_harvest_maxbyday %>%
ggplot(aes(x = date, y = weight_kg)) +
geom_col(aes(fill = vegetable), position = "dodge") +
scale_y_continuous(expand = c(0, 0)) +
scale_fill_hue() +
labs(x= "",
y = "Weight(kg)" ,
fill = "Vegetable")

Instructor’s feedback: (copy the feedback from moodle here)
I love this idea - very creative! Because there are so many
vegetables, the color legend is tricky to read. I think there might be a
couple reasons. So, first, after summarizing your data, use fct_drop()
to get rid of any unused vegetable levels. Then, create a 2nd graph that
is a barplot with vegetable on the y-axis and the number of times they
were the maximum on the x-axis. Eventually you’ll add that inside this
plot, but for now, it can be separate. Fill the bars by vegetable name
but remove the legend and remove it in the orginal graph, too. This new
plot will take the place of the original legend, while providing even
more information. Add a title that communicates what’s in the plot - you
may also need a subtitle since it’s a bit complex.
Graph Week 2
Question I hope to answer: (probably the same as previous week but
may change slightly) I’m still going to try to look at the what the
greatest yield crop is each day, but I’m going to add some
clarifications as you suggested. I’m also starting to think about what I
could do to expand this question, because I feel like it’s a little too
simple to work on for the rest of the semester.
garden_harvest_maxbyday <- garden_harvest %>%
group_by(date, vegetable) %>%
summarize(veg_total = sum(weight)) %>%
mutate(weight_kg = veg_total/1000) %>%
slice_max(weight_kg, n= 1) %>%
ungroup() %>%
group_by(vegetable) %>%
mutate(n = n()) %>%
arrange(desc(n))
garden_harvest_maxbyday
garden_harvest_maxbyday %>%
ggplot(aes(y = weight_kg, x = date)) +
geom_col(aes(fill = fct_reorder(vegetable, n)), position = "dodge") +
scale_y_continuous(limits = c(0,50),expand = c(0, 0)) +
scale_fill_hue() +
geom_text(aes(label = vegetable), angle = 90, check_overlap = TRUE, hjust = -.2) +
labs(x= "",
y = "Weight(kg)" ,
fill = "Vegetable")

garden_harvest %>%
group_by(date, vegetable) %>%
summarize(veg_total = sum(weight)) %>%
mutate(weight_kg = veg_total/1000) %>%
slice_max(weight_kg, n= 1) %>%
ungroup() %>%
group_by(vegetable) %>%
summarize(n = n()) %>%
ggplot(aes(y = fct_reorder(vegetable, n), x = n)) +
geom_col(aes(fill = fct_reorder(vegetable, n))) +
scale_fill_hue()

Instructor’s feedback: (copy the feedback from moodle here)
Great! In the first plot, add weight (kg) to the title and omit the
y-axis label. Omit the legend since the 2nd graph is really going to be
used as the legend - while providing additional information. Omit the
vertical gird lines using a theme() argument. In the second graph, omit
the legend, y-axis label, and horizontal grid lines. Use
scale_x_continuous(expand = c(0,0)) to move the y-axis labels right next
to the bars.
Graph Week 3
Question I hope to answer: (probably the same as previous week but
may change slightly)
I’m still going to look at what the highest yield is on each harvest,
but I want to add some more information from the dataset using
plotly.
garden_harvest_maxbyday <- garden_harvest %>%
group_by(date, vegetable) %>%
summarize(veg_total = sum(weight)) %>%
mutate(weight_kg = veg_total/1000) %>%
slice_max(weight_kg, n= 1) %>%
ungroup() %>%
group_by(vegetable) %>%
mutate(n = n()) %>%
arrange(desc(n)) %>%
mutate(weekday = wday(date, label = TRUE))
garden_harvest_maxbyday
maxbyday_plot <- garden_harvest_maxbyday %>%
ggplot(aes(y = weight_kg, x = date)) +
geom_col(aes(fill = fct_reorder(vegetable, n),
label = vegetable,
group = weekday),
position = "dodge") +
scale_y_continuous(limits = c(0,50),expand = c(0, 0)) +
scale_fill_hue() +
#geom_text(aes(label = vegetable), angle = 90, check_overlap = TRUE, hjust = -.2) +
labs(x= "",
y = NULL,
title = "Weight (kg) of most bountiful harvest by day",
fill = NULL) +
theme(legend.position ="none",
panel.grid.major.x = element_blank())
ggplotly(maxbyday_plot,
tooltip = c("vegetable",
"date",
"weight_kg",
"veg_total",
"weekday"))
I wanted to add plotly features to this graph as well but it would
never allow interaction when I tried. Is there some way I could fix
that? Also, is ther some way I can change the label that appears in the
tooltip?
veg_most_max <- garden_harvest %>%
group_by(date, vegetable) %>%
summarize(veg_total = sum(weight)) %>%
mutate(weight_kg = veg_total/1000) %>%
slice_max(weight_kg, n= 1) %>%
ungroup() %>%
group_by(vegetable) %>%
summarize(n = n()) %>%
ggplot(aes(y = fct_reorder(vegetable, n), x = n)) +
geom_col(aes(fill = fct_reorder(vegetable, n))) +
scale_fill_hue() +
scale_x_continuous(expand = c(0, 0)) +
theme(legend.position ="none",
panel.grid.major.y = element_blank()) +
labs(x = "Count of '#1' harvests",
y= NULL)
veg_most_max

Instructor’s feedback: (copy the feedback from moodle here)
Graph Week 4
Question I hope to answer: (probably the same as previous week but
may change slightly)
Instructor’s feedback: (copy the feedback from moodle here)
Graph Week 5
Question I hope to answer: (probably the same as previous week but
may change slightly)
Instructor’s feedback: (copy the feedback from moodle here)
LS0tDQp0aXRsZTogIlBlcmZlY3QgR2FyZGVuIEdyYXBoIg0KYXV0aG9yOiAiU2V0aCBCdWVzaW5nIg0Kb3V0cHV0OiANCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZmxvYXQ6IHRydWUNCiAgICBkZl9wcmludDogcGFnZWQNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UpDQpgYGANCg0KYGBge3IgbGlicmFyaWVzfQ0KbGlicmFyeSh0aWR5dmVyc2UpICAgICAgICAgIyBmb3IgZ3JhcGhpbmcgYW5kIGRhdGEgY2xlYW5pbmcNCmxpYnJhcnkoZ2d0aGVtZXMpDQpsaWJyYXJ5KGx1YnJpZGF0ZSkgICAgICAgICAjIGZvciB3b3JraW5nIHdpdGggZGF0ZXMNCmxpYnJhcnkoY29sb3JSYW1wcykNCmxpYnJhcnkocmVtb3RlcykNCmxpYnJhcnkocGxvdGx5KQ0KIyBGb3IgdGhlIGdhcmRlbiBkYXRhLCB5b3UgbmVlZCB0byBmaXJzdCBpbnN0YWxsIHRoZSByZW1vdGVzIGxpYnJhcnksIGlmIHlvdSBoYXZlbid0IGFscmVhZHkNCiMgVGhlbiwgaW5zdGFsbCB0aGUgZ2FyZGVuUiBsaWJyYXJ5LCBpZiB5b3UgaGF2ZW4ndCBhbHJlYWR5LiBEbyB0aGlzIGJ5IHVuY29tbWVudGluZyB0aGUgY29kZSBiZWxvdyAoZGVsZXRlIHRoZSBoYXNodGFnKSBhbmQgcnVubmluZyBpdC4gVGhlbiwgeW91IHNob3VsZCBkZWxldGUgdGhpcyBsaW5lIG9mIGNvZGUgb3IgYWRkIHRoZSBoYXNodGFnIGJhY2sgc28geW91IGRvbid0IHJlaW5zdGFsbCBlYWNoIHRpbWUuDQojIGByZW1vdGVzOjppbnN0YWxsX2dpdGh1YigibGxlbmR3YXkvZ2FyZGVuUiIpDQojIE9uY2UgdGhlIGxpYnJhcnkgaXMgaW5zdGFsbGVkLCB5b3UgZG9uJ3QgbmVlZCB0byBpbnN0YWxsIGl0IGFnYWluLCBidXQgZWFjaCB0aW1lIHlvdSBuZWVkIHRvIGxvYWQgdGhlIGxpYnJhcnkgdXNpbmcgdGhlIGNvZGUgYmVsb3cuIFlvdSB3aWxsIGtub3cgaWYgeW91IGhhdmVuJ3QgaW5zdGFsbGVkIHRoZSBsaWJyYXJ5IGlmIHRoZSBjb2RlIGJlbG93IHByb2R1Y2VzIGFuIGVycm9yLg0KbGlicmFyeShnYXJkZW5SKQ0KdGhlbWVfc2V0KHRoZW1lX21pbmltYWwoKSkgICMgc2V0IGEgdGhlbWUgaWYgZGVzaXJlZA0KYGBgDQoNCmBgYHtyIGRhdGF9DQojIGxvYWQgdGhlIGdhcmRlbiBkYXRhIA0KZGF0YShnYXJkZW5faGFydmVzdCkNCmBgYA0KDQpFeHBsYWluIHRoZSBxdWVzdGlvbiB5b3UgaG9wZSB0byBhbnN3ZXIgYW5kIGNyZWF0ZSB0aGUgZ3JhcGggYmVsb3cgaW4gdGhlIEdyYXBoIFdlZWsgMSBzZWN0aW9uLiBGb3IgdGhlIGZpcnN0IHdlZWssIHlvdSBtYXkgbm90IGhhdmUgdGhlIHNraWxscyBxdWl0ZSB5ZXQgdG8gY3JlYXRlIGV4YWN0bHkgd2hhdCB5b3Ugd2FudCB0byBjcmVhdGUgLSB0aGF0J3Mgb2shIEdldCBhcyBjbG9zZSBhcyB5b3UgY2FuLCBhbmQgdGhlIGluc3RydWN0b3JzIHdpbGwgZ2l2ZSB5b3UgZmVlZGJhY2sgdG8gaGVscCB5b3Ugb3V0LiBZb3UgY2FuIHN1bW1hcml6ZSB0aGUgZGF0YSBpbiBhbnkgd2F5IHlvdSdkIGxpa2UuIEFkZCBSIGNvZGUgY2h1bmtzIGFuZCBjb21tZW50IGNvZGUgYXMgbmVlZGVkLiBBcyB0aGUgd2Vla3MgZ28gYnksIHlvdSB3aWxsIGNvbnRpbnVlIHRvIGJ1aWxkIG9uIHRoaXMgZmlsZSBieSBwdXR0aW5nIG5ldyBjb2RlIGluIHRoZSBuZXh0IEdyYXBoIHNlY3Rpb25zLiBZb3Ugd2lsbCBrZWVwIGFsbCB0aGUgb2xkIGNvZGUsIGFkZCB5b3VyIGluc3RydWN0b3IncyBmZWVkYmFjayBieSBjb3B5aW5nIGFuZCBwYXN0aW5nIGl0IGZyb20gbW9vZGxlIChmb3VuZCBpbiB0aGUgR3JhZGUgc2VjdGlvbiBvZiBtb29kbGUpLCBhbmQgbWFrZSBpbXByb3ZlbWVudHMgZnJvbSBteSBzdWdnZXN0aW9ucyBhbmQgZnJvbSBvdGhlciBpZGVhcyB5b3UgaGF2ZS4gSGF2aW5nIHRoZSBvbGQgY29kZSBhbmQgZ3JhcGhzIGFuZCB0aGUgaW5zdHJ1Y3RvciBmZWVkYmFjayB3aWxsIGhlbHAgeW91IChhbmQgdGhlIGluc3RydWN0b3JzKSBlYXNpbHkgc2VlIHRoZSBwcm9ncmVzcyB0aHJvdWdob3V0IHRoZSBjb3Vyc2UuDQoNCkZZSSwgUHJvZi4gTGlzYSBqdXN0IGFkZGVkIDIwMjEgZGF0YSB0byB0aGUgYGdhcmRlblJgIHBhY2thZ2UuIElmIHlvdSB3YW50IHRvIHVzZSB0aGF0IGRhdGEgKGVpdGhlciB3aXRoIHRoZSAyMDIwIGRhdGEgb3IgYnkgaXRzZWxmKSwgeW91IHdpbGwgbmVlZCB0byByZWluc3RhbGwgdGhlIHBhY2thZ2UuIEp1c3QgYSB3YXJuaW5nIHRoYXQgdmFyaWFibGUgbmFtZXMgd2VyZSBtYWludGFpbmVkIGJ1dCBuYW1lcyBvZiB2ZWdldGFibGVzIGFuZCB2YXJpZXRpZXMgY2hhbmdlZCBpbiBhIGZldyBjYXNlcyBvdmVyIHRoZSB0d28geWVhcnMgKG9vcHMpLiBBZnRlciB5b3UgbG9hZCB0aGUgZGF0YXNldCwgeW91IGNhbiBzZWFyY2ggZm9yIGdhcmRlblIgaW4gdGhlIEhlbHAgdGFiIHRvIGZpbmQgb3V0IG1vcmUgYWJvdXQgdGhlIG5ldyBkYXRhc2V0cy4NCg0KIyMgR3JhcGggV2VlayAxDQoNClF1ZXN0aW9uIEkgaG9wZSB0byBhbnN3ZXI6ICh3cml0ZSB5b3VyIGRlc2NyaXB0aW9uIGhlcmUgLSAxLTIgc2VudGVuY2VzIHNob3VsZCBiZSBwbGVudHkpDQoNCkknbSBnb2luZyB0byB0cnkgdG8gc2VlIHdoYXQgdGhlIGdyZWF0ZXN0IHlpZWxkIGNyb3AgaXMgb3ZlciB0aW1lLSB3aGljaCB0aW1lIG9mIHN1bW1lciBpcyB0aGUgImJlYW4iIHNlYXNvbiB2cy4gInBlYSBzZWFzb24iLiBNeSBhcHByb2FjaCBpcyBnb2luZyB0byBiZSBmaW5kaW5nIHRoZSBtYXhpbXVtIHZlZ2V0YWJsZSBoYXJ2ZXN0ZWQgZWFjaCBkYXksIGFuZCBkaXNwbGF5aW5nIHRoZSB3ZWlnaHQgaGFydmVzdGVkIGFzIHdlbGwuDQoNCmBgYHtyfQ0KZ2FyZGVuX2hhcnZlc3RfbWF4YnlkYXkgPC0gZ2FyZGVuX2hhcnZlc3QgJT4lIA0KICAgIGdyb3VwX2J5KGRhdGUsIHZlZ2V0YWJsZSkgJT4lIA0KICAgICAgc3VtbWFyaXplKHZlZ190b3RhbCA9IHN1bSh3ZWlnaHQpKSAgJT4lIA0KICAgICAgICAgIG11dGF0ZSh3ZWlnaHRfa2cgPSB2ZWdfdG90YWwvMTAwMCkgJT4lIA0KICAgICAgICAgICAgc2xpY2VfbWF4KHdlaWdodF9rZywgbj0gMSkNCmBgYA0KDQpUaGUgZGF0YSBzaG91bGQgbm93IGJlIGdyb3VwZWQgYnkgdGhlIG1heGltdW0gdmVnZXRhYmxlIGhhcnZlc3RlZCBlYWNoIGRheSwgYW5kIHRoZSB3ZWlnaHQgaGFydmVzdGVkLg0KDQpgYGB7ciwgZmlnLmhlaWdodCA9IDEwLCBmaWcud2lkdGggPSAxNH0NCiAgICBnYXJkZW5faGFydmVzdF9tYXhieWRheSAlPiUgDQogICAgICAgIGdncGxvdChhZXMoeCA9IGRhdGUsIHkgPSB3ZWlnaHRfa2cpKSArDQogICAgICAgIGdlb21fY29sKGFlcyhmaWxsID0gdmVnZXRhYmxlKSwgcG9zaXRpb24gPSAiZG9kZ2UiKSArDQogICAgICAgIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBjKDAsIDApKSArDQogICAgICAgIHNjYWxlX2ZpbGxfaHVlKCkgKw0KICAgICAgICBsYWJzKHg9ICIiLA0KICAgICAgICAgICAgIHkgPSAiV2VpZ2h0KGtnKSIgLA0KICAgICAgICAgICAgIGZpbGwgPSAiVmVnZXRhYmxlIikNCmBgYA0KDQoNCkluc3RydWN0b3IncyBmZWVkYmFjazogKGNvcHkgdGhlIGZlZWRiYWNrIGZyb20gbW9vZGxlIGhlcmUpDQoNCgkNCkkgbG92ZSB0aGlzIGlkZWEgLSB2ZXJ5IGNyZWF0aXZlISBCZWNhdXNlIHRoZXJlIGFyZSBzbyBtYW55IHZlZ2V0YWJsZXMsIHRoZSBjb2xvciBsZWdlbmQgaXMgdHJpY2t5IHRvIHJlYWQuIEkgdGhpbmsgdGhlcmUgbWlnaHQgYmUgYSBjb3VwbGUgcmVhc29ucy4gU28sIGZpcnN0LCBhZnRlciBzdW1tYXJpemluZyB5b3VyIGRhdGEsIHVzZSBmY3RfZHJvcCgpIHRvIGdldCByaWQgb2YgYW55IHVudXNlZCB2ZWdldGFibGUgbGV2ZWxzLiBUaGVuLCBjcmVhdGUgYSAybmQgZ3JhcGggdGhhdCBpcyBhIGJhcnBsb3Qgd2l0aCB2ZWdldGFibGUgb24gdGhlIHktYXhpcyBhbmQgdGhlIG51bWJlciBvZiB0aW1lcyB0aGV5IHdlcmUgdGhlIG1heGltdW0gb24gdGhlIHgtYXhpcy4gRXZlbnR1YWxseSB5b3UnbGwgYWRkIHRoYXQgaW5zaWRlIHRoaXMgcGxvdCwgYnV0IGZvciBub3csIGl0IGNhbiBiZSBzZXBhcmF0ZS4gRmlsbCB0aGUgYmFycyBieSB2ZWdldGFibGUgbmFtZSBidXQgcmVtb3ZlIHRoZSBsZWdlbmQgYW5kIHJlbW92ZSBpdCBpbiB0aGUgb3JnaW5hbCBncmFwaCwgdG9vLiBUaGlzIG5ldyBwbG90IHdpbGwgdGFrZSB0aGUgcGxhY2Ugb2YgdGhlIG9yaWdpbmFsIGxlZ2VuZCwgd2hpbGUgcHJvdmlkaW5nIGV2ZW4gbW9yZSBpbmZvcm1hdGlvbi4gQWRkIGEgdGl0bGUgdGhhdCBjb21tdW5pY2F0ZXMgd2hhdCdzIGluIHRoZSBwbG90IC0geW91IG1heSBhbHNvIG5lZWQgYSBzdWJ0aXRsZSBzaW5jZSBpdCdzIGEgYml0IGNvbXBsZXguDQoNCiMjIEdyYXBoIFdlZWsgMg0KDQpRdWVzdGlvbiBJIGhvcGUgdG8gYW5zd2VyOiAocHJvYmFibHkgdGhlIHNhbWUgYXMgcHJldmlvdXMgd2VlayBidXQgbWF5IGNoYW5nZSBzbGlnaHRseSkNCkknbSBzdGlsbCBnb2luZyB0byB0cnkgdG8gbG9vayBhdCB0aGUgd2hhdCB0aGUgZ3JlYXRlc3QgeWllbGQgY3JvcCBpcyBlYWNoIGRheSwgYnV0IEknbSBnb2luZyB0byBhZGQgc29tZSBjbGFyaWZpY2F0aW9ucyBhcyB5b3Ugc3VnZ2VzdGVkLiBJJ20gYWxzbyBzdGFydGluZyB0byB0aGluayBhYm91dCB3aGF0IEkgY291bGQgZG8gdG8gZXhwYW5kIHRoaXMgcXVlc3Rpb24sIGJlY2F1c2UgSSBmZWVsIGxpa2UgaXQncyBhIGxpdHRsZSB0b28gc2ltcGxlIHRvIHdvcmsgb24gZm9yIHRoZSByZXN0IG9mIHRoZSBzZW1lc3Rlci4NCg0KYGBge3J9DQpnYXJkZW5faGFydmVzdF9tYXhieWRheSA8LSBnYXJkZW5faGFydmVzdCAlPiUgDQogIGdyb3VwX2J5KGRhdGUsIHZlZ2V0YWJsZSkgJT4lIA0KICBzdW1tYXJpemUodmVnX3RvdGFsID0gc3VtKHdlaWdodCkpICAlPiUgDQogIG11dGF0ZSh3ZWlnaHRfa2cgPSB2ZWdfdG90YWwvMTAwMCkgJT4lIA0KICBzbGljZV9tYXgod2VpZ2h0X2tnLCBuPSAxKSAlPiUgDQogIHVuZ3JvdXAoKSAlPiUNCiAgZ3JvdXBfYnkodmVnZXRhYmxlKSAlPiUgDQogIG11dGF0ZShuID0gbigpKSAlPiUgDQogIGFycmFuZ2UoZGVzYyhuKSkNCmdhcmRlbl9oYXJ2ZXN0X21heGJ5ZGF5DQpgYGANCg0KYGBge3IsIGZpZy5oZWlnaHQgPSAxMCwgZmlnLndpZHRoID0gMTQsIGZpZy5hbHQgPSAiIn0NCiAgZ2FyZGVuX2hhcnZlc3RfbWF4YnlkYXkgJT4lIA0KICAgICAgICBnZ3Bsb3QoYWVzKHkgPSB3ZWlnaHRfa2csIHggPSBkYXRlKSkgKw0KICAgICAgICBnZW9tX2NvbChhZXMoZmlsbCA9IGZjdF9yZW9yZGVyKHZlZ2V0YWJsZSwgbikpLCBwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgICAgICAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMCw1MCksZXhwYW5kID0gYygwLCAwKSkgKw0KICAgICAgICBzY2FsZV9maWxsX2h1ZSgpICsNCiAgICAgICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHZlZ2V0YWJsZSksIGFuZ2xlID0gOTAsIGNoZWNrX292ZXJsYXAgPSBUUlVFLCBoanVzdCA9IC0uMikgKw0KICAgICAgICBsYWJzKHg9ICIiLA0KICAgICAgICAgICAgIHkgPSAiV2VpZ2h0KGtnKSIgLA0KICAgICAgICAgICAgIGZpbGwgPSAiVmVnZXRhYmxlIikNCmBgYA0KDQoNCmBgYHtyfQ0KZ2FyZGVuX2hhcnZlc3QgJT4lIA0KICBncm91cF9ieShkYXRlLCB2ZWdldGFibGUpICU+JSANCiAgc3VtbWFyaXplKHZlZ190b3RhbCA9IHN1bSh3ZWlnaHQpKSAgJT4lIA0KICBtdXRhdGUod2VpZ2h0X2tnID0gdmVnX3RvdGFsLzEwMDApICU+JSANCiAgc2xpY2VfbWF4KHdlaWdodF9rZywgbj0gMSkgJT4lIA0KICB1bmdyb3VwKCkgJT4lDQogIGdyb3VwX2J5KHZlZ2V0YWJsZSkgJT4lIA0KICBzdW1tYXJpemUobiA9IG4oKSkgJT4lDQogICAgZ2dwbG90KGFlcyh5ID0gZmN0X3Jlb3JkZXIodmVnZXRhYmxlLCBuKSwgeCA9IG4pKSArDQogICAgICBnZW9tX2NvbChhZXMoZmlsbCA9IGZjdF9yZW9yZGVyKHZlZ2V0YWJsZSwgbikpKSArDQogICAgICBzY2FsZV9maWxsX2h1ZSgpDQpgYGANCg0KSW5zdHJ1Y3RvcidzIGZlZWRiYWNrOiAoY29weSB0aGUgZmVlZGJhY2sgZnJvbSBtb29kbGUgaGVyZSkNCg0KR3JlYXQhIEluIHRoZSBmaXJzdCBwbG90LCBhZGQgd2VpZ2h0IChrZykgdG8gdGhlIHRpdGxlIGFuZCBvbWl0IHRoZSB5LWF4aXMgbGFiZWwuIE9taXQgdGhlIGxlZ2VuZCBzaW5jZSB0aGUgMm5kIGdyYXBoIGlzIHJlYWxseSBnb2luZyB0byBiZSB1c2VkIGFzIHRoZSBsZWdlbmQgLSB3aGlsZSBwcm92aWRpbmcgYWRkaXRpb25hbCBpbmZvcm1hdGlvbi4gT21pdCB0aGUgdmVydGljYWwgZ2lyZCBsaW5lcyB1c2luZyBhIHRoZW1lKCkgYXJndW1lbnQuIEluIHRoZSBzZWNvbmQgZ3JhcGgsIG9taXQgdGhlIGxlZ2VuZCwgeS1heGlzIGxhYmVsLCBhbmQgaG9yaXpvbnRhbCBncmlkIGxpbmVzLiBVc2Ugc2NhbGVfeF9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwwKSkgdG8gbW92ZSB0aGUgeS1heGlzIGxhYmVscyByaWdodCBuZXh0IHRvIHRoZSBiYXJzLg0KDQojIyBHcmFwaCBXZWVrIDMNCg0KUXVlc3Rpb24gSSBob3BlIHRvIGFuc3dlcjogKHByb2JhYmx5IHRoZSBzYW1lIGFzIHByZXZpb3VzIHdlZWsgYnV0IG1heSBjaGFuZ2Ugc2xpZ2h0bHkpDQoNCkknbSBzdGlsbCBnb2luZyB0byBsb29rIGF0IHdoYXQgdGhlIGhpZ2hlc3QgeWllbGQgaXMgb24gZWFjaCBoYXJ2ZXN0LCBidXQgSSB3YW50IHRvIGFkZCBzb21lIG1vcmUgaW5mb3JtYXRpb24gZnJvbSB0aGUgZGF0YXNldCB1c2luZyBwbG90bHkuDQoNCg0KYGBge3J9DQpnYXJkZW5faGFydmVzdF9tYXhieWRheSA8LSBnYXJkZW5faGFydmVzdCAlPiUgDQogIGdyb3VwX2J5KGRhdGUsIHZlZ2V0YWJsZSkgJT4lIA0KICBzdW1tYXJpemUodmVnX3RvdGFsID0gc3VtKHdlaWdodCkpICAlPiUgDQogIG11dGF0ZSh3ZWlnaHRfa2cgPSB2ZWdfdG90YWwvMTAwMCkgJT4lIA0KICBzbGljZV9tYXgod2VpZ2h0X2tnLCBuPSAxKSAlPiUgDQogIHVuZ3JvdXAoKSAlPiUgDQogIGdyb3VwX2J5KHZlZ2V0YWJsZSkgJT4lIA0KICBtdXRhdGUobiA9IG4oKSkgJT4lIA0KICBhcnJhbmdlKGRlc2MobikpICU+JSANCiAgbXV0YXRlKHdlZWtkYXkgPSB3ZGF5KGRhdGUsIGxhYmVsID0gVFJVRSkpDQpnYXJkZW5faGFydmVzdF9tYXhieWRheQ0KYGBgDQoNCmBgYHtyLCBmaWcuaGVpZ2h0ID0gMTAsIGZpZy53aWR0aCA9IDE0LCBmaWcuYWx0ID0gIkdyYXBoIG9mIG1vc3QgaGFydmVzdGVkIHZlZ2V0YWJsZSBlYWNoIGRheS4gTm90YWJseSwgdGhlIHB1bXBraW5zIGhhZCBhIHNtYWxsIG51bWVyIG9mIGhpZ2ggeWllbGQgZGF5cyBsYXRlciBpbiB0aGUgc2Vhc29uLCB3aGlsZSB0aGUgdG9tYXRvZXMgY29uc2lzdGVudGx5IHBlcmZvcm1lZCB3ZWxsIG92ZXIgYSBsb25nZXIgcGVyaW9kIG9mIHRpbWUuICJ9DQogIG1heGJ5ZGF5X3Bsb3QgPC0gZ2FyZGVuX2hhcnZlc3RfbWF4YnlkYXkgJT4lIA0KICAgICAgICBnZ3Bsb3QoYWVzKHkgPSB3ZWlnaHRfa2csIHggPSBkYXRlKSkgKw0KICAgICAgICBnZW9tX2NvbChhZXMoZmlsbCA9IGZjdF9yZW9yZGVyKHZlZ2V0YWJsZSwgbiksDQogICAgICAgICAgICAgICAgICAgICBsYWJlbCA9IHZlZ2V0YWJsZSwNCiAgICAgICAgICAgICAgICAgICAgIGdyb3VwID0gd2Vla2RheSksDQogICAgICAgICAgICAgICAgIHBvc2l0aW9uID0gImRvZGdlIikgKw0KICAgICAgICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLDUwKSxleHBhbmQgPSBjKDAsIDApKSArDQogICAgICAgIHNjYWxlX2ZpbGxfaHVlKCkgKw0KICAgICAgICAjZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHZlZ2V0YWJsZSksIGFuZ2xlID0gOTAsIGNoZWNrX292ZXJsYXAgPSBUUlVFLCBoanVzdCA9IC0uMikgKw0KICAgICAgICBsYWJzKHg9ICIiLA0KICAgICAgICAgICAgIHkgPSBOVUxMLA0KICAgICAgICAgICAgIHRpdGxlID0gIldlaWdodCAoa2cpIG9mIG1vc3QgYm91bnRpZnVsIGhhcnZlc3QgYnkgZGF5IiwNCiAgICAgICAgICAgICBmaWxsID0gTlVMTCkgKw0KICAgICAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSJub25lIiwNCiAgICAgICAgICAgICAgcGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9ibGFuaygpKQ0KICANCiAgZ2dwbG90bHkobWF4YnlkYXlfcGxvdCwNCiAgICAgICAgICAgdG9vbHRpcCA9IGMoInZlZ2V0YWJsZSIsDQogICAgICAgICAgICAgICAgICAgICAgICJkYXRlIiwgDQogICAgICAgICAgICAgICAgICAgICAgICJ3ZWlnaHRfa2ciLA0KICAgICAgICAgICAgICAgICAgICAgICAidmVnX3RvdGFsIiwNCiAgICAgICAgICAgICAgICAgICAgICAgIndlZWtkYXkiKSkNCmBgYA0KDQpJIHdhbnRlZCB0byBhZGQgcGxvdGx5IGZlYXR1cmVzIHRvIHRoaXMgZ3JhcGggYXMgd2VsbCBidXQgaXQgd291bGQgbmV2ZXIgYWxsb3cgaW50ZXJhY3Rpb24gd2hlbiBJIHRyaWVkLiBJcyB0aGVyZSBzb21lIHdheSBJIGNvdWxkIGZpeCB0aGF0PyBBbHNvLCBpcyB0aGVyIHNvbWUgd2F5IEkgY2FuIGNoYW5nZSB0aGUgbGFiZWwgdGhhdCBhcHBlYXJzIGluIHRoZSB0b29sdGlwPw0KYGBge3IsIGZpZy5hbHQgPSAiQSBiYXIgZ3JhcGggZGlzcGxheWluZyBob3cgb2Z0ZW4gYSB2ZWdldGFibGUvZnJ1aXQgd2FzIHRoZSBncmVhdGVzdC15aWVsZCBjb250cmlidXRvciBpbiBhIGRheS4gVGhlIHRvbWF0b2VzIHdlcmUgdGhlIGdyZWF0ZXN0IHlpZWxkIHRoZSBtb3N0IG9mdGVuLCB3aXRoIG92ZXIgMzUgZGF5cyBhcyBoaWdoZXN0IGhhcnZlc3QuICJ9DQogIHZlZ19tb3N0X21heCA8LSBnYXJkZW5faGFydmVzdCAlPiUgDQogICAgZ3JvdXBfYnkoZGF0ZSwgdmVnZXRhYmxlKSAlPiUgDQogICAgc3VtbWFyaXplKHZlZ190b3RhbCA9IHN1bSh3ZWlnaHQpKSAgJT4lIA0KICAgIG11dGF0ZSh3ZWlnaHRfa2cgPSB2ZWdfdG90YWwvMTAwMCkgJT4lIA0KICAgIHNsaWNlX21heCh3ZWlnaHRfa2csIG49IDEpICU+JSANCiAgICB1bmdyb3VwKCkgJT4lDQogICAgZ3JvdXBfYnkodmVnZXRhYmxlKSAlPiUgDQogICAgc3VtbWFyaXplKG4gPSBuKCkpICU+JQ0KICAgICAgZ2dwbG90KGFlcyh5ID0gZmN0X3Jlb3JkZXIodmVnZXRhYmxlLCBuKSwgeCA9IG4pKSArDQogICAgICAgIGdlb21fY29sKGFlcyhmaWxsID0gZmN0X3Jlb3JkZXIodmVnZXRhYmxlLCBuKSkpICsNCiAgICAgICAgc2NhbGVfZmlsbF9odWUoKSArDQogICAgICAgIHNjYWxlX3hfY29udGludW91cyhleHBhbmQgPSBjKDAsIDApKSArDQogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0ibm9uZSIsDQogICAgICAgICAgcGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpKSArDQogICAgbGFicyh4ID0gIkNvdW50IG9mICcjMScgaGFydmVzdHMiLA0KICAgICAgICAgeT0gTlVMTCkNCiAgICANCiAgICB2ZWdfbW9zdF9tYXgNCmBgYA0KDQpJbnN0cnVjdG9yJ3MgZmVlZGJhY2s6IChjb3B5IHRoZSBmZWVkYmFjayBmcm9tIG1vb2RsZSBoZXJlKQ0KDQojIyBHcmFwaCBXZWVrIDQNCg0KUXVlc3Rpb24gSSBob3BlIHRvIGFuc3dlcjogKHByb2JhYmx5IHRoZSBzYW1lIGFzIHByZXZpb3VzIHdlZWsgYnV0IG1heSBjaGFuZ2Ugc2xpZ2h0bHkpDQoNCmBgYHtyfQ0KYGBgDQoNCkluc3RydWN0b3IncyBmZWVkYmFjazogKGNvcHkgdGhlIGZlZWRiYWNrIGZyb20gbW9vZGxlIGhlcmUpDQoNCiMjIEdyYXBoIFdlZWsgNQ0KDQpRdWVzdGlvbiBJIGhvcGUgdG8gYW5zd2VyOiAocHJvYmFibHkgdGhlIHNhbWUgYXMgcHJldmlvdXMgd2VlayBidXQgbWF5IGNoYW5nZSBzbGlnaHRseSkNCg0KYGBge3J9DQpgYGANCg0KSW5zdHJ1Y3RvcidzIGZlZWRiYWNrOiAoY29weSB0aGUgZmVlZGJhY2sgZnJvbSBtb29kbGUgaGVyZSk=